﻿#ifndef DATATYPES_H
#define DATATYPES_H

#include <QString>
#include <QList>
#include <QMap>
#include <QVariant>
#include <QSharedPointer>
#include "deviceattributes.h"

enum TestProcessStage {
    LevelScanning = 0x0, //电平扫描
    Calibration,         //校准
    Testing              //测试
};

enum HardwareTemplateType {
    RS = 0x0,
    CS
};

enum class AxisScale {
    Linear = 0x0,
    Logarithmic
};

// 硬件模板
struct HardwareTemplate {
    int id = 0;
    QString name = "";
    HardwareTemplateType type;
    double frequencyMin = 10000; //最小频率，单位（Hz）
    double frequencyMax = 100e9; //最大频率，单位（Hz）

    GeneratorConfigPtr d_Generator;                        //信号源
    AmplifierConfigPtr d_Amplifier;                        //功放
    PowerMeterConfigPtr d_FwdPowerMeter;                   //正向功率计
    PowerMeterConfigPtr d_RevPowerMeter;                   //反向功率计
    AntennaConfigPtr d_RadiatesAntenna;                    //辐射天线
    AntennaConfigPtr d_ReceivesAntenna;                    //接收天线
    CurrentInjectionProbeConfigPtr d_InjectionTransducer;  //注频转换器
    CurrentInjectionProbeConfigPtr d_MonitoringTransducer; //监测转换器
    PowerMeterConfigPtr d_MonPowerMeter;                   //监测功率计
    FieldProbesConfigPtr d_MonFieldProbes;                 //监测场强仪
    SpectrumAnalyzerConfigPtr d_MonSpectrumAnalyzer;       //监测频谱仪
    ReceiverConfigPtr d_MonReceiver;                       //监测接收机
    ConnectorConfigPtr c_SIG2PA;
    ConnectorConfigPtr c_FWD2PM;
    ConnectorConfigPtr c_REV2PM;
    ConnectorConfigPtr c_PA2Transducers;
    ConnectorConfigPtr c_Transducers2PM;
};
using HardwareTemplatePtr = QSharedPointer<HardwareTemplate>;

enum class ParamTableKind {
    Default = -1,
    Attenuation = 0x0,
    Transducer,
    LimitLine,
    Frequency,
    Cal
};

// 轻量级概览结构，用于UI列表显示
struct OverviewItem {
    int id = -1;
    QString name = "";
    ParamTableKind type = ParamTableKind::Default; // e.g., "AttTable", "TransducerTable", "LimitLine", "FreqTable", "CalResult"
    HardwareTemplateType hwType = HardwareTemplateType::RS;
};

/************************* 表 **********************/

// 衰减表
struct AttTableConfig {
    double Freq = 0; //频率
    double Att = 0;  //衰减
};
struct AttTableList {
    AxisScale xAxisScale = AxisScale::Linear; // 描述刻度类型
    AxisScale yAxisScale = AxisScale::Linear;
    QVector<AttTableConfig> attList;
};
using AttTableListPtr = QSharedPointer<AttTableList>;

/// 频率表
struct FreqTableConfig {
    double Freq = 0; //频率
};
using FreqTableConfigListPtr = QSharedPointer<QVector<FreqTableConfig>>;

struct FactorsConfig {
    double Freq = 0;    //频率
    double Factors = 0; //因子：使用时进行线性插值
};

//换能器，天线或电流探头
struct TransducerTableList {
    AxisScale xAxisScale = AxisScale::Linear; // 描述刻度类型
    AxisScale yAxisScale = AxisScale::Linear;
    QString xUnit = "MHz";
    QString yUnit = "dBm";
    QString sourceUnit = "dBm"; // 源单位
    QString targetUnit = "V/m"; // 目标单位
    QVector<FactorsConfig> factorsList;
};
using TransducerTableListPtr = QSharedPointer<TransducerTableList>;

// 极值表
struct LimitLineConfig {
    double Freq = 0;  //频率 单位 Hz
    double Limit = 0; //极值
};
struct LimitLineList {
    QString xUnit = "MHz";
    QString yUnit = "V/m";
    AxisScale xAxisScale = AxisScale::Linear; // 描述刻度类型
    AxisScale yAxisScale = AxisScale::Linear;
    QVector<LimitLineConfig> limitList;
};
using LimitLineListPtr = QSharedPointer<LimitLineList>;

// 参照校准表
struct CalTableConfig {
    double Freq = 1;                   //频率 单位 Hz
    double Amplitude = -100;           //幅度
    double FwdPower = -30;             //正向功率
    double RevPower = -30;             //反向功率
    double ImmunityLevel = 0;          //实际抗干扰等级
    double LimitImmunityLevel = 0;     //限值(额定干扰等级)
    double swr = 1;                    //驻波比
    double Loss = 0;                   //衰减补偿
    bool CloseLoop = false;            //是否闭环调试过
    QString info = "-,-,-,-,-,-";      //(频段、步进模式、LNE值、LOG值、驻留时间、调制方式）
    QString ImmunityLevelUnit = "V/m"; //抗干扰等级单位
};
struct CalibrationDataList {
    QString name = ""; //表名
    QVector<CalTableConfig> calDataList;
};
using CalibrationDataListPtr = QSharedPointer<CalibrationDataList>;

/************************ 测试模板 **********************/

enum GeneratorModulationType {
    Off = 0x0,
    AM,
    FM,
    PM
};
enum class FrequencyPlanType {
    SweepLinear = 0,
    FreqTableOnly,
    FreqTablePlusStep
};

// 抗扰电平来源
enum class ImmunityLevelType {
    Fixed,
    Table
};
// 测试子区间
struct TestSubBand {
    int id = 0;
    int hardwareTemplateID;                                                     //硬件模板Id
    double startFreq = 0;                                                       //起始频率 单位Hz
    double stopFreq = 1;                                                        //终止频率 单位Hz
    AxisScale stepMode = AxisScale::Linear;                                     //步进模式 log:%, line: MHz
    double stepSize = 1e6;                                                      //频率步长 默认1MHz
    double dwellTime = 0;                                                       //停顿时间 单位ms
    FrequencyPlanType freqPlan = FrequencyPlanType::SweepLinear;                //频率模式
    int freqTableID = 0;                                                        //频率表ID
    ImmunityLevelType immunityLevelType = ImmunityLevelType::Fixed;             //抗干扰电平类型 0：使用固定值如 1W 1：使用抗干扰电平表格
    int immunityLevelTableID = 0;                                               //极值表 id
    double immunityLevelValue = 22.3;                                           //抗干扰电平值
    double upperTolerance = 0.2;                                                //测试误差上范围 电位dB
    double lowerTolerance = 0.2;                                                //测试误差下范围 电位dB
    GeneratorModulationType generatorModulation = GeneratorModulationType::Off; // 信号源调制 0：关闭功能，1：AM 2:FM 3:PM
    double plumPeriod = 0;                                                      //周期   单位 us
    double plumWidth = 0;                                                       //脉宽   单位 us
};

using TestSubBandPtr = QSharedPointer<TestSubBand>;

//功率测量选项，与界面中选项顺序一一对应，界面中选项顺序改变影响此功能调用结果
enum PowerMeasurementType {
    Generator_Level = 0x0, //发生器电平
    Forwrd_Power,          //前向功率
    Net_Power              //净功率
};

enum LevelModeType {
    SubstitutionMethod = 0x0, //替换法
    Sensor                    //探头法
};

enum AntennaFactorType {
    Vertical = 0x0,
    Horizontal
};

// 测试模板
struct TestTemplate {
    int id = 0;
    QString name = "";
    HardwareTemplateType flowKind = HardwareTemplateType::RS;                      //模板类型 存入数据库
    TestProcessStage stage = TestProcessStage::Calibration;                        //用于构建测试流程，没有存入数据库
    LevelModeType levelMode = LevelModeType::Sensor;                               //启动控制电平 1:探头法，0:替换法
    PowerMeasurementType powerMeasurement = PowerMeasurementType::Generator_Level; //功率测量
    QString immunityLevelUnit = "V/m";                                             //抗干扰电平单位 目前只支持两种单位 V/m, dBuA
    double impedance = 50;                                                         //功率转换阻抗 默认：50 Ohms
    int calibrationDataID;                                                         //校准数据
    int offsetCheck = 0;                                                           //cs测试，Sensor时可以选择极限值补偿
    double offset = 0;                                                             //cs测试，Sensor时使用的补偿值
    AntennaFactorType antennaFactor = AntennaFactorType::Vertical;                 //天线因子,用于构建测试计划，没有存到数据库中
    QVector<TestSubBandPtr> subBands;                                              //子区间

    //以下参数只用于控制Customplot轨迹显示，不参与数据计算，不与其0它数据相关联。
    int CheckGeneratorOutput = 1; //发生器输出
    double GeneratorOutputYmax = 200;
    double GeneratorOutputYmin = -200;
    AxisScale GeneratorOutputXAxisScale = AxisScale::Linear;
    AxisScale GeneratorOutputYAxisScale = AxisScale::Linear;
    int CheckAmplifierFP = 1; //功放前向功率
    double AmplifierFPYmax = 200;
    double AmplifierFPYmin = -200;
    AxisScale AmplifierFPXAxisScale = AxisScale::Linear;
    AxisScale AmplifierFPYAxisScale = AxisScale::Linear;
    int CheckAmplifierRP = 1; //功放反向功率
    double AmplifierRPYmax = 200;
    double AmplifierRPYmin = -200;
    AxisScale AmplifierRPXAxisScale = AxisScale::Linear;
    AxisScale AmplifierRPYAxisScale = AxisScale::Linear;
    int CheckVSWR; //驻波比
    double VSWRYmax = 10;
    double VSWRYmin = -10;
    AxisScale VSWRXAxisScale = AxisScale::Linear;
    AxisScale VSWRYAxisScale = AxisScale::Linear;
    int CheckImmunityLevel = 1; //抗干扰电平
    double ImmunityLevelYmax = 200;
    double ImmunityLevelYmin = -10;
    AxisScale ImmunityLevelXAxisScale = AxisScale::Linear;
    AxisScale ImmunityLevelYAxisScale = AxisScale::Linear;
};
using TestTemplatePtr = QSharedPointer<TestTemplate>;

namespace Exec {

// 通用插值曲线（只读）
struct Curve {
    QVector<double> xs_Hz;                // 升序（Hz）
    QVector<double> ys;                   // y 值（单位取决于业务：dB/dBm/V/m…）
    AxisScale xScale = AxisScale::Linear; // 线性/对数插值（x 轴）
    AxisScale yScale = AxisScale::Linear; // y 轴是否在对数域插值（通常线性）
    QString sourceUnit = "dBm";           // 源单位, , 天线和电流探头使用，RS只转为V/m ， CS只能转为dBuA，设置错误构建计划失败。
    QString targetUnit = "V/m";           // 目标单位 , 天线和电流探头使用，RS只转为V/m ， CS只能转为dBuA，设置错误构建计划失败。
};
using CurvePtr = QSharedPointer<const Curve>;

// 校准表（只读，单位统一）
struct CalPoint {
    double freq_Hz = 0;
    double amplitude_dBm = -100;
    double fwd_dBm = -30;
    double rev_dBm = -30;
    double immunityLevel = 0; // 实际抗扰等级（与 unit 一致，如 V/m）
    double limit = 0;         // 限值（与 unit 一致）
    double swr = 1.0;
    double loss_dB = 0;
    bool closeLoop = false;
    QString info;
    QString immunityUnit = "V/m";
};
using CalTable = QVector<CalPoint>;
using CalTablePtr = QSharedPointer<const CalTable>;

struct Hardware {
    QString name;
    HardwareTemplateType type = HardwareTemplateType::RS;
    double fmin_Hz = 0; //表示设备的运行范围，可用于判断测试区间频率范围是否超过了硬件的工作范围
    double fmax_Hz = 0; //表示设备的运行范围，可用于判断测试区间频率范围是否超过了硬件的工作范围

    // 设备配置采用值拷贝，避免测试时修改。
    QSharedPointer<const GeneratorConfig> gen;
    QSharedPointer<const AmplifierConfig> amp;
    QSharedPointer<const PowerMeterConfig> fwdPM, revPM, monPM;
    QSharedPointer<const AntennaConfig> antTx, antRx;
    QSharedPointer<const CurrentInjectionProbeConfig> inj, mon;
    QSharedPointer<const FieldProbesConfig> fieldProbe;
    QSharedPointer<const ReceiverConfig> rec;
    QSharedPointer<const SpectrumAnalyzerConfig> sa;
    QSharedPointer<const ConnectorConfig> c_sig2pa, c_fwd2pm, c_rev2pm, c_pa2tr, c_tr2pm;

    // 运行期需要的响应/补偿表，统一编译成曲线
    CurvePtr ampCouplerFwd;
    CurvePtr ampCouplerRev; // 来自 AttTable（dB）
    CurvePtr antHFactors;   // 来自 Transducer
    CurvePtr antVFactors;   // 来自 Transducer
    CurvePtr probeFactors;  // 来自 Transducer 电流探头因子
    CurvePtr probeCorr;     // 来自 Transducer 场强探头修正

    CurvePtr con_gen2Amp;
    CurvePtr con_Fwd2Pm;
    CurvePtr con_Rev2Pm;
    CurvePtr con_amp2Tran;   //功放到 天线/电流探头
    CurvePtr con_tran2MonPM; //天线/电流探头到 功率计
};
using HardwarePtr = QSharedPointer<const Hardware>;

// 子区间快照
struct Subrange {
    int id = 0;
    double spanFmin_Hz = 0;
    double spanFmax_Hz = 0;

    double dwell_ms = 0; // 驻留时间
    GeneratorModulationType modulation = GeneratorModulationType::Off;
    double plumPeriod = 0; //周期   单位 us
    double plumWidth = 0;  //脉宽   单位 us

    double upperTol_dB = 0, lowerTol_dB = 0; // 判定容差
    ImmunityLevelType levelSrc = ImmunityLevelType::Fixed;
    double fixedImmunityLevel = 0; // 与 immunityUnit 一致（如 V/m）

    // 只读引用
    HardwarePtr hw;                // 解析后的硬件模板
    QVector<double> freqPoints_Hz; // 预展开频点
    CurvePtr limitCurve;           // 若 levelSrc=Table，则使用限值线表（y 单位与 immunityUnit 一致）
    CalTablePtr cal;               //替代法测试时，使用的参照校准表, cs测试探头法也会用到

    // 新增：对齐后的硬件相关曲线（可选添加你需要的）
    CurvePtr ampCouplerFwdAligned;
    CurvePtr ampCouplerRevAligned;
    CurvePtr antHFactorsAligned;
    CurvePtr antVFactorsAligned;
    CurvePtr probeFactorsAligned; //电流探头因子
    CurvePtr probeCorrAligned;
    CurvePtr con_gen2AmpAligned;
    CurvePtr con_Fwd2PmAligned;
    CurvePtr con_Rev2PmAligned;
    CurvePtr con_amp2TranAligned;
    CurvePtr con_tran2MonPMAligned;
};
using SubrangeList = QVector<Subrange>;

// 可执行测试计划（只读）
struct TestPlan {
    int id = 0;
    int stage = TestProcessStage::Calibration;
    int flowKind = 0; //取第一个子区间中的硬件type cs或rs，testbuilder中需要校验各子区间内硬件模板类型是否一致。
    QString name;

    int levelMode = LevelModeType::Sensor;
    int powerMeasurement = PowerMeasurementType::Generator_Level;
    QString immunityUnit = "V/m"; //所有子区间内单位保持一致
    double impedance_Ohm = 50;
    int antennaFactor = AntennaFactorType::Vertical; //天线因子

    int cs_offsetCheck = 0; //cs测试，Sensor时可以选择是否补偿，（如果选择补偿时，必须选择校准表）
    double cs_offset = 0;   //cs测试，Sensor时可以选择是否补偿，（如果选择补偿时，必须选择校准表）

    SubrangeList subranges;
};
using TestPlanPtr = QSharedPointer<const TestPlan>;

} // namespace Exec

struct MeasurementPoint {
    int subrangeIndex = 0;
    int frequencyIndex = 0;
    bool isPass = true;
    QString errorMessage;

    CalTableConfig calTable;
};

struct LevelScanningData {
    int scanCount = 1;             //扫描次数
    QVector<double> freqPoints_Hz; // 预展开频点
    QVector<double> levelPoints;   //单位 dBm | dBuV
};

struct TestFlowCallbacks {
    std::function<bool()> isStopRequested;                          // 上层是否请求停止
    std::function<void()> waitIfPaused;                             // 若上层暂停则阻塞等待
    std::function<void(const QString &)> logLine;                   // 记录日志
    std::function<void(MeasurementPoint &)> progress;               // 流式进度回传
    std::function<void(LevelScanningData &)> levelScanData;         // 环境扫描数据
    std::function<void(DeviceMeasureStatus &)> deviceMeasureStatus; // 测试时设备状态
};
struct FlowPlanOptions {
    TestProcessStage stage = TestProcessStage::Calibration; // 你定义的阶段枚举
    LevelModeType levelMode = LevelModeType::Sensor;
    PowerMeasurementType powerMeasurement = PowerMeasurementType::Generator_Level;
    QString immunityUnit = "V/m";
    double impedanceOhm = 50.0;
    AntennaFactorType antennaFactor = AntennaFactorType::Vertical; //天线因子

    int cs_offsetCheck = 0; //cs测试，Sensor时可以选择是否补偿，（如果选择补偿时，必须选择校准表）
    double cs_offset = 0;   //cs测试，Sensor时可以选择是否补偿，（如果选择补偿时，必须选择校准表）
};

struct LevelScanningConfig {
    TestProcessStage stage = TestProcessStage::LevelScanning;
    HardwareTemplateType type = HardwareTemplateType::RS;

    GeneralAttributes gAttributes; //目前只支持接收机
    double freqStart_Hz = 10000;
    double freqStop_Hz = 500000;
    double freqStep_Hz = 10000;
    AxisScale stepMode = AxisScale::Linear; //步进模式 log:%, line: MHz
    double refLevel = -10;
    QString powerUnit = "dBm"; //辐射时为dBm，传导时为dBuV
    double inputAtten = 10;    //输入衰减
    double dwellTime = 0.001;  //驻留时间，单位s

    double safetyMargin = 6.0; //安全裕度
    int factorTableID = 0;
    int attTableID = 0; //线损表
    int repeatCont = 1; //重复次数
};

#endif // DATATYPES_H
